package com.kusiri.kframework.metadata
{
	import com.kusiri.kframework.KfContext;
	import com.kusiri.kframework.component.property.IKfComponentProperty;
	import com.kusiri.kframework.component.property.IKfComponentPropertyEditor;
	import com.kusiri.kframework.component.property.IKfComponentPropertyViewer;
	import com.kusiri.kframework.component.property.component.KfComponentComponentPropertyEditor;
	import com.kusiri.kframework.component.property.string.KfComponentStringPropertyEditor;
	
	import flash.utils.describeType;
	import flash.utils.getDefinitionByName;
	
	import mx.controls.Text;
	import mx.core.IFlexDisplayObject;
	
	/**
	 * Metadata for properties of a certain component class
	 */
	public class KfComponentPropertyMetadata
	{
		/**
		 * 
		 */
		protected var _clazz : Class;
		
		/**
		 * 
		 */
		protected var _clazzDescription : XML;
		
		/**
		 * 
		 */
		protected var _name : String;
		
		/**
		 * 
		 */
		protected var _type : String;
		
		/**
		 * 
		 */
		protected var _label : String;
		
		/**
		 * 
		 */
		public function KfComponentPropertyMetadata(name:String, type:String, label:String)
		{
			_name = name;
			_type = type;
			_label = label;
			_clazz = getDefinitionByName(_type) as Class;	
			if (_clazz) _clazzDescription = describeType(_clazz).factory[0];
		}
		
		/**
		 * 
		 */
		public function get name() : String
		{
			return _name;
		}
		
		/**
		 * 
		 */
		public function get label() : String
		{
			return _label;
		}
		
		/**
		 * 
		 */
		public function get type() : String
		{
			return _type;
		}
		
		/**
		 * Converts an XML property definition to a value
		 */
		public function getPropertyValueFromConfiguration( context : KfContext, propertyConfiguration : KfComponentPropertyConfiguration) : *
		{
			var propertyAsXml : XML = propertyConfiguration.value;
			
			if ( _type == 'String' || _type == 'int' || _type == 'float' || _type == 'Number' )
			{
				return propertyAsXml.toString();
			}
			
			if ( _type == 'Boolean' ) return propertyAsXml.toString() == 'true';
			
			if (_clazzDescription.implementsInterface.(@type=="com.kusiri.kframework.component::IKfComponent")[0] != null)
			{
				return context.getComponentWithoutInitializing(propertyAsXml.toString());
			}

			var componentProperty : IKfComponentProperty = new _clazz();
			componentProperty.__initialize(propertyAsXml.*[0]);
			return componentProperty;
		}
		
//		/**
//		 * Converts a property value to the XML format
//		 */
//		public function getPropertyValueAsConfiguration(propertyValue : *) : XML
//		{
//				
//			if ( type == 'String' || type == 'int' || type == 'float' || type == 'Number' )
//			{
//				return <property name={_name}>{propertyValue}</property>;
//			}
//			
//			if ( type == 'Boolean' )
//			{
//				return <property name={_name}>{propertyValue ? 'true' : 'false'}</property>;
//			}
//			
//			if (propertyValue is IKfComponent)
//			{
//				return <property name={_name}>{(propertyValue as IKfComponent).__name}</property>;
//			}
//			
//			var componentProperty : IKfComponentProperty = propertyValue as IKfComponentProperty;
//			
//			return <property name={_name}>{componentProperty.__toXml()}</property>;
//		}
		
		public function isKfComponent() : Boolean
		{
			if (_clazz == null) return false;
			return _clazzDescription.implementsInterface.(@type=="com.kusiri.kframework.component::IKfComponent")[0] != null;
		}
		

		/**
		 * 
		 */
		public function newViewer( appconfig : KfApplicationConfiguration, configuration : KfComponentPropertyConfiguration ) : IFlexDisplayObject
		{
			if ( _type == 'String' || _type == 'int' || _type == 'float' || _type == 'Number' || _type == 'Boolean')
			{
				var uiComponent : Text = new Text();
				uiComponent.text = configuration.value;
				return uiComponent;
			}
			
			if ( isKfComponent() )
			{
				var kfcomponentView : Text = new Text();
				var componentConfiguration : KfComponentConfiguration = appconfig.getComponentConfiguration(configuration.value.toString());
				kfcomponentView.text = componentConfiguration.name;
				return kfcomponentView;
			}
			
			
			var componentProperty : IKfComponentProperty = new _clazz();
			var clazz : Class = componentProperty.__viewerClass();
			var kfViewer : IKfComponentPropertyViewer = new clazz();
			kfViewer.configuration = configuration.value;
			return kfViewer;
		}
		
		/**
		 * 
		 */
		public function newEditor( appconfig : KfApplicationConfiguration, configuration : KfComponentPropertyConfiguration ) : IKfComponentPropertyEditor
		{
			var editor : IKfComponentPropertyEditor;
			var clazz : Class;
			
			if ( _type == 'String')
			{
				editor = new KfComponentStringPropertyEditor();
			}
			else if ( _type == 'int' )
			{
				editor = new KfComponentStringPropertyEditor();
			}
			else if ( _type == 'Number' )
			{
				editor = new KfComponentStringPropertyEditor();
			}
			else if ( _type == 'Boolean' )
			{
				editor = new KfComponentStringPropertyEditor();
			}
			else if ( _type == 'Boolean' )
			{
				editor = new KfComponentStringPropertyEditor();
			}
			else if ( isKfComponent() )
			{
				editor = new KfComponentComponentPropertyEditor();
				(editor as KfComponentComponentPropertyEditor).components = appconfig.getComponentsImplementing(_type);
			}
			else
			{
				var componentProperty : IKfComponentProperty = new _clazz();
				clazz = componentProperty.__editorClass();
				editor = new clazz();
			}
			
			editor.configuration = configuration.value;
			return editor;
		}
		
	}
}